package com.inetools.gwetons.client.cssStyleChangerBySelector;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;

import com.inetools.gwetons.shared.logging.LogUtil;
import com.inetools.gwetons.shared.logging.LogUtilAdapterTemplate;

/**
 * To keep track of changes made progressibly via StyleChangerTimerEvent object. <br />
 * Used only when values of both of initValue property and endValue property are numeric integers 
 * (including represented as string) and value of interval property is smaller than value of period property. 
 * @author ay
 */
class StyleChangerState extends LogUtilAdapterTemplate {
	@Override
	protected String getNameForLogging() {
		return this.getClass().getName();
	}

	static enum State {
		InitValue( 0), EndValue( 1), CurrentValue( 2), DiffUnit( 3), 
		InitRed( 4), EndRed( 5), CurrentRed( 6), RedDiffUnit( 7), 
		InitGreen( 8), EndGreen( 9), CurrentGreen( 10), GreenDiffUnit( 11),
		InitBlue( 12), EndBlue( 13), CurrentBlue( 14), BlueDiffUnit( 15);
		
		int index;
			int getIndex() {
				return index;
			}

		State( int index) {
			this.index = index;
		}
	}
	
	List<Integer> stateValues = new ArrayList<Integer>( State.values().length);
	
	public Integer getStateValue( State state) {
		if ( state == null) {
			throw new IllegalArgumentException( 
					"null is not allowed as states argument.");
		}
		
		String methodName = "getStateValue";
		LogUtil logUtil = getLogUtil();
		logUtil.entering( methodName, new Object[]{ "states(=" + state.toString() + ")"});
		
		Integer value = stateValues.get( state.getIndex());
		
		logUtil.exiting( methodName, value);
		return value;
	}
	public void setStateValue( State state, int value) {
		if ( state == null) {
			throw new IllegalArgumentException( 
					"null is not allowed as states argument.");
		}
		
		String methodName = "setStateValue";
		LogUtil logUtil = getLogUtil();
		logUtil.entering( 
				methodName, new Object[]{ "states(=" + state.toString() + ")", "value(=" + value + ")"});
		
		stateValues.set( state.getIndex(), Integer.valueOf( value));
		
		logUtil.exiting( methodName);
	}
	boolean isInitialized( State state) {
		if ( state == null) {
			throw new IllegalArgumentException( 
					"null is not allowed as states argument.");
		}
		
		String methodName = "isInitialized";
		LogUtil logUtil = getLogUtil();
		logUtil.entering( methodName, new Object[]{ "states(=" + state.toString() + ")"});
		
		boolean returningResult = ((getStateValue( state) == null) ? false : true);
		
		logUtil.exiting( methodName, returningResult);
		return returningResult;
	}
	
	Boolean isEndReached() {
		String methodName = "reverse";
		LogUtil logUtil = getLogUtil();
		logUtil.entering( methodName, null);
		
		if ( getStateValue( State.DiffUnit) == null) {
			logUtil.log( Level.INFO, "Value of " + State.DiffUnit.toString() + " is null.");
			logUtil.exiting( methodName, null);
			return null;
		}
		if ( getStateValue( State.EndValue) == null) {
			logUtil.log( Level.INFO, "Value of " + State.EndValue.toString() + " is null.");
			logUtil.exiting( methodName, null);
			return null;
		}
		if ( getStateValue( State.CurrentValue) == null) {
			logUtil.log( Level.INFO, "Value of " + State.CurrentValue.toString() + " is null.");
			logUtil.exiting( methodName, null);
			return null;
		}
		
		int sign = 1;
		if ( getStateValue( State.DiffUnit).intValue() < 0) {
			sign = -1;
		}
		
		int difference 
		= sign * (getStateValue( State.EndValue).intValue() - getStateValue( State.CurrentValue).intValue()); 
		if ( difference > 0) {
			logUtil.exiting( methodName, false);
			return false;
		}
		
		logUtil.exiting( methodName, true);
		return true;
	}
	
	boolean isAtReverseState = false;
		boolean isAtReverseState() {
			return isAtReverseState;
		}
		
	void reverse() {
		String methodName = "reverse";
		LogUtil logUtil = getLogUtil();
		logUtil.entering( methodName, null);
		
		isAtReverseState = !isAtReverseState;
		
		Collections.swap( stateValues, State.InitValue.getIndex(), State.EndValue.getIndex());
		if ( isInitialized( State.DiffUnit)) {
			setStateValue( State.DiffUnit, (getStateValue( State.DiffUnit).intValue() * -1));
		}
		Collections.swap( stateValues, State.InitRed.getIndex(), State.EndRed.getIndex());
		if ( isInitialized( State.RedDiffUnit)) {
			setStateValue( State.RedDiffUnit, (getStateValue( State.RedDiffUnit).intValue() * -1));
		}
		Collections.swap( stateValues, State.InitGreen.getIndex(), State.EndGreen.getIndex());
		if ( isInitialized( State.GreenDiffUnit)) {
			setStateValue( State.GreenDiffUnit, (getStateValue( State.GreenDiffUnit).intValue() * -1));
		}
		Collections.swap( stateValues, State.InitBlue.getIndex(), State.EndBlue.getIndex());
		if ( isInitialized( State.BlueDiffUnit)) {
			setStateValue( State.BlueDiffUnit, (getStateValue( State.BlueDiffUnit).intValue() * -1));
		}
		
		logUtil.exiting( methodName);
	}
} // protected class StyleChangerState